/*
 * 础光实时操作系统PhotonRTOS -- 位查找实现文件
 *
 * Copyright (C) 2022, 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Baoyou Xie <xiebaoyou@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include <photon/bitops.h>
#include <photon/types.h>

#define BITMAP_LAST_WORD_MASK(nbits)					\
(									\
	((nbits) % BITS_PER_LONG) ?					\
		(1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL		\
)

/**
 * __fls - find last (most-significant) set bit in a intptr_t word
 * @word: the word to search
 *
 * Undefined if no set bit exists, so code should check against 0 first.
 */
static  uintptr_t __fls(uintptr_t word)
{
	return (sizeof(word) * 8) - 1 - __builtin_clzl(word);
}


#ifndef find_last_bit
uint32_t find_last_bit(const uintptr_t *addr, uintptr_t size)
{
	if (size != (uintptr_t)0) {
		uintptr_t val = BITMAP_LAST_WORD_MASK(size);
		uintptr_t idx = ((size-1) / BITS_PER_LONG) + 1;

		do {
			idx--;
			val &= addr[idx];
			if (val != (uintptr_t)0) {
				return idx * BITS_PER_LONG + __fls(val);
			}

			val = ~0UL;
		} while (idx != (uintptr_t)0);
	}
	return size;
}
#endif
